home *** CD-ROM | disk | FTP | other *** search
-
- #include "Colors.h"
- #include "BDAssert.h"
- #include <algobase.h>
- #include <stdio.h>
-
- ///////////////////////////////////////////////////////////////////////////////
- //
- // Initialize colors
- //
-
- // Mac Standard Colors
- const RGBColor RGB_WHITE = { 0xFFFF, 0xFFFF, 0xFFFF };
- const RGBColor RGB_BLACK = { 0x0000, 0x0000, 0x0000 };
- const RGBColor RGB_YELLOW = { 0xFC00, 0xF37D, 0x052F };
- const RGBColor RGB_MAGENTA = { 0xF2D7, 0x0856, 0x84EC };
- const RGBColor RGB_RED = { 0xDD6B, 0x08C2, 0x06A2 };
- const RGBColor RGB_CYAN = { 0x0241, 0xAB54, 0xEAFF };
- const RGBColor RGB_GREEN = { 0x0000, 0x8000, 0x11B0 };
- const RGBColor RGB_BLUE = { 0x0000, 0x0000, 0xD400 };
-
- // Mac non-standard colors
- const RGBColor RGB_GRAY = { 0x8080, 0x8080, 0x8080 }; // same as COLORREF_GRAY
- const RGBColor RGB_LTGRAY = { 0xC0C0, 0xC0C0, 0xC0C0 }; // same as COLORREF_LTGRAY
- const RGBColor RGB_BROWN = { 0x0000, 0x8080, 0x8080 }; // same as COLORREF_BROWN
-
- // Windows standards, taken from Intrinsic tickctl.h, OLE_COLORs
- const RGBColor COLORREF_RED = { 0x0000, 0x0000, 0x8080 };
- const RGBColor COLORREF_GREEN = { 0x0000, 0x8080, 0x0000 };
- const RGBColor COLORREF_BLUE = { 0x8080, 0x0000, 0x0000 };
- const RGBColor COLORREF_MAGENTA = { 0x8080, 0x0000, 0x8080 };
- const RGBColor COLORREF_CYAN = { 0x8080, 0x8080, 0x0000 };
- const RGBColor COLORREF_BLACK = { 0x0000, 0x0000, 0x0000 };
- const RGBColor COLORREF_YELLOW = { 0x0000, 0xFFFF, 0xFFFF };
- const RGBColor COLORREF_WHITE = { 0xFFFF, 0xFFFF, 0xFFFF };
- // (ones that don't have a direct match on Mac)
- const RGBColor COLORREF_LTRED = { 0x0000, 0x0000, 0xFFFF };
- const RGBColor COLORREF_LTGREEN = { 0x0000, 0xFFFF, 0x0000 };
- const RGBColor COLORREF_LTBLUE = { 0xFFFF, 0x0000, 0x0000 };
- const RGBColor COLORREF_LTMAGENTA = { 0xFFFF, 0x0000, 0xFFFF };
- const RGBColor COLORREF_LTCYAN = { 0xFFFF, 0xFFFF, 0x0000 };
- // (bonus colors -- ones that have no match at all on Mac)
- const RGBColor COLORREF_GRAY = { 0x8080, 0x8080, 0x8080 };
- const RGBColor COLORREF_LTGRAY = { 0xC0C0, 0xC0C0, 0xC0C0 };
- const RGBColor COLORREF_BROWN = { 0x0000, 0x8080, 0x8080 };
-
- const short SIZEOF_MATCHING_COLORS = 8; // update this if you add to the array!
- const RGBColor * MATCHING_COLORS[] =
- {
- &COLORREF_RED, // <-- same as COLORREF_LTRED (matching index!)
- &COLORREF_GREEN, // <-- same as COLORREF_LTGREEN (matching index!)
- &COLORREF_BLUE, // <-- same as COLORREF_LTBLUE (matching index!)
- &COLORREF_MAGENTA, // <-- same as COLORREF_LTMAGENTA (matching index!)
- &COLORREF_CYAN, // <-- same as COLORREF_LTCYAN (matching index!)
- &COLORREF_BLACK,
- &COLORREF_YELLOW,
- &COLORREF_WHITE
- };
-
- const short SIZEOF_CLOSE_COLORS = 5; // update this if you add to the array!
- const RGBColor * CLOSE_COLORS[] =
- {
- &COLORREF_LTRED, // <-- treat as COLORREF_RED (matching index!)
- &COLORREF_LTGREEN, // <-- treat as COLORREF_GREEN (matching index!)
- &COLORREF_LTBLUE, // <-- treat as COLORREF_BLUE (matching index!)
- &COLORREF_LTMAGENTA, // <-- treat as COLORREF_MAGENTA (matching index!)
- &COLORREF_LTCYAN, // <-- treat as COLORREF_CYAN (matching index!)
- };
-
- const short SIZEOF_BONUS_COLORS = 3; // update this if you add to the array!
- const RGBColor * BONUS_COLORS[] =
- {
- &COLORREF_GRAY,
- &COLORREF_LTGRAY,
- &COLORREF_BROWN
- };
-
- ///////////////////////////////////////////////////////////////////////////////
- //
- // MapColorRefToRGBColor
- //
-
- void MapColorRefToRGBColor(const COLORREF * desiredColorRef, RGBColor * desiredRGBColor, Boolean useColorMatching)
- {
- // A COLORREF in Windows is a triplet of bytes. An RGBColor is
- // a triplet of shorts (two bytes). The input for the color is in the
- // format #00bbggrr (hex), indicating a COLORREF (one-byte triplet), not
- // an RGBColor (two-byte triplet). One way to translate would be to simply map
- // a one-byte range into a two-byte range (as below). This would not map colors
- // very well. But we'll start with that.
-
- // Range mapping:
- desiredRGBColor->red = desiredColorRef->red * CONVERSION;
- desiredRGBColor->green = desiredColorRef->green * CONVERSION;
- desiredRGBColor->blue = desiredColorRef->blue * CONVERSION;
-
- // What we'll do now is try to match the standard nearest system color,
- // making the assumption that most people will be using something pretty
- // standard for the stock ticker. We'll even add some smarts for special
- // cases like primary colors red, green, and blue (note that, for instance,
- // a COLORREF of "red" is {0x00, 0x00, 0xff} -- not much like RGB_RED).
-
- if ( useColorMatching )
- {
- // Find the closest color match (crude algorithm)
-
- unsigned short delta = 0;
- short i = 0;
-
- // first, search in the set of colors defined on windows and mac
- unsigned long matchingDelta;
- short matchingIndex = -1;
- MatchColor(desiredRGBColor, MATCHING_COLORS, SIZEOF_MATCHING_COLORS, matchingDelta, matchingIndex);
-
- // next, search the set of colors that have close, but not exact
- // matches on the mac.
- unsigned long closeDelta;
- short closeIndex = -1;
- MatchColor(desiredRGBColor, CLOSE_COLORS, SIZEOF_CLOSE_COLORS, closeDelta, closeIndex);
-
- // finally, search the set of colors that have no real standard match
- // on the mac
- unsigned long bonusDelta;
- short bonusIndex = -1;
- MatchColor(desiredRGBColor, BONUS_COLORS, SIZEOF_BONUS_COLORS, bonusDelta, bonusIndex);
-
- // if the closest match we've found is in the "matching" list, do the
- // translation. If it's in the "close" list, use the closest match
- // in the "matching" list, by using the corresponding array index.
- // If it's in the "bonus" list, invent our own.
-
- if ( bonusDelta == MIN3(matchingDelta, closeDelta, bonusDelta) )
- SET_COLOR(*desiredRGBColor, BONUS_COLORS[bonusIndex]) // ;
- else
- {
- short theIndex = closeIndex;
- if ( matchingDelta == MIN3(matchingDelta, closeDelta, bonusDelta) )
- theIndex = matchingIndex;
- SET_COLOR(*desiredRGBColor, MATCHING_COLORS[theIndex]) // ;
- }
- }
- }
-
- ///////////////////////////////////////////////////////////////////////////////
- //
- // MatchColor
- //
-
- void MatchColor (
- const RGBColor * targetColor,
- const RGBColor ** colorPtrArray,
- short arraySize,
- unsigned long & delta,
- short & index )
- {
- delta = 0xFFFFFFFF;
- index = -1;
-
- unsigned long newDelta;
-
- for ( short i = 0; i < arraySize; i++ )
- {
- newDelta = RGBDELTA((colorPtrArray[i]), targetColor);
-
- if ( newDelta <= delta )
- {
- delta = newDelta;
- index = i;
- }
- }
- }
-
-
- ///////////////////////////////////////////////////////////////////////////////
- //
- // RGBColorsEQ
- //
- // returns true if the input colors are identical
- //
-
- Boolean RGBColorsEQ ( const RGBColor & color1, const RGBColor & color2 )
- {
- Boolean colorsAreEqual = true;
-
- if ( color1.red != color2.red ||
- color1.green != color2.green ||
- color1.blue != color2.blue )
- colorsAreEqual = false;
-
- return colorsAreEqual;
- }
-
-
- ///////////////////////////////////////////////////////////////////////////////
- //
- // RGBColorsPERCENT
- //
- // color the color we want a percentage of
- // percent the percent of a color expressed as a value from 0.0 to 1.0
- //
- // returns a weighted value of the RGBColor passed in
- //
-
- RGBColor RGBColorsPERCENT(const RGBColor color, const double percent)
- {
- // first check out the percent to make sure that it is in range:
- #ifdef _DEBUG
- assert(percent <= 1.0 && percent >= 0.0);
- #endif
- RGBColor weightedColor;
-
- weightedColor.red = color.red * percent;
- weightedColor.green = color.green * percent;
- weightedColor.blue = color.blue * percent;
-
- return weightedColor;
- }
-
-
- ///////////////////////////////////////////////////////////////////////////////
- //
- // RGBColorsPLUS
- //
- // color1 the first color we want to sum
- // color2 the second color we want to sum
- // returns the sum of two colors
- //
-
- RGBColor RGBColorsPLUS(const RGBColor color1, const RGBColor color2)
- {
- RGBColor additiveColor;
-
- // add each component and make sure it does not exceed the max value
- additiveColor.red = min(MAX_USHORT, color1.red + color2.red);
- additiveColor.green = min(MAX_USHORT, color1.green + color2.green);
- additiveColor.blue = min(MAX_USHORT, color1.blue + color2.blue);
-
- return additiveColor;
- }
-
-
- ///////////////////////////////////////////////////////////////////////////////
- //
- // RGBColorsInterpolate
- //
- // color1 the color we want to subtract from
- // color2 the color we want to subtract
- // returns the sum of two colors
- //
-
- RGBColor RGBColorsInterpolate(const RGBColor color1, const RGBColor color2, double percent)
- {
- // first check out the percent to make sure that it is in range:
- #ifdef _DEBUG
- assert(percent <= 1.0 && percent >= 0.0);
- #endif
- RGBColor interpolatedColor;
- // color1 is our base to interpolate from so we compute the distance between pairs
- // and then multiply by the weight -- that value is then added back to the base
- // to give us the 'final' color. Note that this is done with signed values so it
- // is important which order we subtract in.
-
- // compute the weighted amount of each component (signed value)
- short redOffset = (short)(percent * (double)(color1.red - color2.red));
- short greenOffset = (short)(percent * (double)(color1.green - color2.green));
- short blueOffset = (short)(percent * (double)(color1.blue - color2.blue));
-
- // We always subtract the 2nd color from the 1st and then multiple by something <= 1.0
- // so we can be sure that when we add this back to the 1st coord that it will not
- // overflow a signed short.
- interpolatedColor.red = (unsigned short)((short)(color1.red) - redOffset);
- interpolatedColor.green = (unsigned short)((short)(color1.green) - greenOffset);
- interpolatedColor.blue = (unsigned short)((short)(color1.blue) - blueOffset);
-
- return interpolatedColor;
- }
-
- //end-of-file